package com.wl.dzt.sys.core.dao.select.term;

import com.wl.dzt.sys.core.dao.mate.DataMateBase;
import com.wl.dzt.sys.core.dao.mate.DataMateColumn;
import com.wl.dzt.sys.util.CollectionUtil;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author wl_code@163.com
 * @date 2018/7/5/005
 * @version 1.0
 * @description 条件选项转换器
 * 将查询条件对象转换为sql查询语句条件
 * 
 */
public class TermOptions {

	/**
	 * 转换构造MAP
	 */
	private static final Map<String, TermPaser> PASERS = new HashMap<>();

	/**
	 * 初始化转换构造MAP
	 */
	static {
		// 正向条件
		{
			// 等于
			PASERS.put("=", (clazz, term, fieldName, val) -> String.format(" %s  =  ? ", fieldName));

			// 模糊匹配
			PASERS.put("like", (clazz, term, fieldName, val) -> String.format(" %s  like  ? ", fieldName));

			// 小于
			PASERS.put("<", (clazz, term, fieldName, val) -> String.format(" %s  <  ? ", fieldName));

			// 小于等于
			PASERS.put("<=", (clazz, term, fieldName, val) -> String.format(" %s  <=  ? ", fieldName));

			// 大于
			PASERS.put(">", (clazz, term, fieldName, val) -> String.format(" %s  >   ? ", fieldName));

			// 大于等于
			PASERS.put(">=", (clazz, term, fieldName, val) -> String.format(" %s  >=  ? ", fieldName));

			// in
			PASERS.put("in", (clazz, term, fieldName, val) -> String.format(" %s  in  (%s) ", fieldName, val));

			// 为空
			PASERS.put("isNull", (clazz, term, fieldName, val) -> String.format(" %s  is null  ", fieldName));
		}

		// 逆向条件
		{
			// 不等于
			PASERS.put("!=", (clazz, term, fieldName, val) -> String.format(" %s  !=  ? ", fieldName));

			// 不模糊匹配
			PASERS.put("!like", (clazz, term, fieldName, val) -> String.format(" %s not like  ? ", fieldName));

			// 不in
			PASERS.put("!in", (clazz, term, fieldName, val) -> String.format(" %s  not in  (%s) ", fieldName, val));

			// 不为空
			PASERS.put("!isNull", (clazz, term, fieldName, val) -> String.format(" %s  is not null  ", fieldName));
		}

	}

	/** 转换in */
	private static String toSqlIn(String[] ary) {
		List<String> inArgs = Arrays.asList(ary), list = new ArrayList<>();
		inArgs.forEach(val -> list.add(String.format("'%s'", val)));
		// in 不存在数据的时候 为了防止sql错误动态的加入NULL条件防止异常
		if (ary.length == 0) {
			list.add("'NULL'");
		}
		return CollectionUtil.join(list, ",");
	}

	/**
	 * <b> 转换sql </b>
	 * <p>
	 * 根据查询条件和对应的实体进行sql的转换
	 * </p>
	 * 
	 * @param clazz
	 * @param term
	 * @return
	 */
	public static Map<String, Object> paserTerms(Class<?> clazz, Term term) {
		Map<String, Object> result = new HashMap<>();
		DataMateColumn column = DataMateBase.getTable(clazz).getColumn(term.getField());
		String value = term.getValue() + "", fieldName = column.asFieldName(term.getField()), op = term.getOp();

		// 模糊匹配
		if ("like".equals(op) || "!like".equals(op)) {
			value = String.format("%%%s%%", value);
		}
		// in
		else if (("in".equals(op) || "!in".equals(op)) && (term.getValue() instanceof String[] || term.getValue() == null)) {
			String[] ary = term.getValue() == null ? new String[] {} : (String[]) term.getValue();
			value = toSqlIn(ary);
		}
		// 执行sql转换
		TermPaser myPaser = PASERS.get(op);
		if (myPaser != null) {
			result.put("sql", myPaser.paser(clazz, term, fieldName, value));
			result.put("val", value);
			return result;
		} else {
			return null;
		}
	}

	/**
	 * <b>判断是否是时间</b>
	 * <p>
	 * 判断是否是时间
	 * </p>
	 *
	 * @param val
	 * @return
	 */
	public static boolean isDate(String val) {
		return (val.contains(":") && val.contains("-") && val.contains("T"));
	}

	private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	/**
	 * <b>小于等于时间修复</b>
	 * <p>
	 * 小于等于时间修复
	 * </p>
	 *
	 * @param val
	 * @return
	 */
	public static String paserDateLq(String val) {
		String strDate = val.replaceAll("T", " ");
		try {
			Date date = dateFormat.parse(strDate);
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			if ((calendar.get(Calendar.HOUR) == 0 && calendar.get(Calendar.MINUTE) == 0)) {
				calendar.set(Calendar.HOUR, 23);
				calendar.set(Calendar.MINUTE, 59);
				calendar.set(Calendar.SECOND, 59);
			}
			return dateFormat.format(calendar.getTime());
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return val;
	}

	/**
	 * <b>大于等于时间修复</b>
	 * <p>
	 * 大于等于时间修复
	 * </p>
	 *
	 * @param val
	 * @return
	 */
	public static String paserDateTq(String val) {
		String strDate = val.replaceAll("T", " ");
		try {
			Date date = dateFormat.parse(strDate);
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			return dateFormat.format(calendar.getTime());
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return val;
	}
}
